#ifndef QQTLONGDATASERIALIZATION_H
#define QQTLONGDATASERIALIZATION_H

#include <QObject>

#include <qqtdataserialization.h>
#include <qqthighgrade_global.h>
/**
 * @brief The QQtLongDataSerialization class
 * 4字节size 数据序列化、反序列化。
 *
 * 原理：
 * Dict ---- Buffer
 * 内部有QByteArray，按照以下格式，
 * 可以通过serialize/unserialize序列化到QByteArray里，和从QByteArray里反序列化到内部字典里。
 *
 * Buffer:
 * |quint32 header|quint32 size|quint8* json_data|quint32 checksum|quint32 tail|
 */
class QQTHIGHGRADESHARED_EXPORT QQtLongDataSerialization : public QQtDataSerialization
{
    Q_OBJECT

public:
    explicit QQtLongDataSerialization ( QObject* parent = 0 );
    virtual ~QQtLongDataSerialization();

    QQtLongDataSerialization ( const QQtLongDataSerialization& other ) {
        *this = other;
    }
    QQtLongDataSerialization& operator= ( const QQtLongDataSerialization& other ) {
        this->buffer() = other.buffer();
        this->dictionary() = other.dictionary();
        return *this;
    }

    //设置value
    template <typename T>
    void addValue ( const T& value ) {
        QQtDataSerialization::addValue<T> ( value );
    }
    /*自己本身没有孩子，是个叶子，添加值*/
    void addValue ( const QVariant& value ) {
        QQtDataSerialization::addValue ( value );
    }

    template <typename T>
    QQtLongDataSerialization& operator = ( const T& value ) {
        QQtDataSerialization::addValue<T> ( value );
        return *this;
    }
    QQtLongDataSerialization& operator = ( const QVariant& value ) {
        QQtDataSerialization& ref = *this;
        ref = value;
        return *this;
    }
    bool operator == ( const QQtLongDataSerialization& other ) {
        if ( dictionary() == other.dictionary() && buffer() == other.buffer() )
            return true;
        return false;
    }

    /**
     * <<
     **/
    //QQtLongDataSerialization& operator<< ( std::nullptr_t ) { return *this; }

    QQtLongDataSerialization& operator<< ( const bool& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }
    QQtLongDataSerialization& operator<< ( const float& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }
    QQtLongDataSerialization& operator<< ( const double& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }


    QQtLongDataSerialization& operator<< ( const quint8& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }
    QQtLongDataSerialization& operator<< ( const quint16& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }
    QQtLongDataSerialization& operator<< ( const quint32& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }
    QQtLongDataSerialization& operator<< ( const quint64& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }

    QQtLongDataSerialization& operator<< ( const qint8& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }
    QQtLongDataSerialization& operator<< ( const qint16& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }
    QQtLongDataSerialization& operator<< ( const qint32& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }
    QQtLongDataSerialization& operator<< ( const qint64& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }

    QQtLongDataSerialization& operator<< ( const char* i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }
    QQtLongDataSerialization& operator<< ( const QByteArray& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }
    QQtLongDataSerialization& operator<< ( const QString& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }
    QQtLongDataSerialization& operator<< ( const QImage& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }

    template <typename T>
    QQtLongDataSerialization& operator<< ( const T& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }
    QQtLongDataSerialization& operator<< ( const QVariant& i ) {
        QQtDataSerialization& ref = *this;
        ref << i;
        return *this;
    }

    /**
     * >>
     **/
    //QQtLongDataSerialization& operator>> ( std::nullptr_t& ptr ) { ptr = nullptr; return *this; }

    QQtLongDataSerialization& operator>> ( bool& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }
    QQtLongDataSerialization& operator>> ( float& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }
    QQtLongDataSerialization& operator>> ( double& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }

    QQtLongDataSerialization& operator>> ( qint8& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }
    QQtLongDataSerialization& operator>> ( qint16& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }
    QQtLongDataSerialization& operator>> ( qint32& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }
    QQtLongDataSerialization& operator>> ( qint64& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }

    QQtLongDataSerialization& operator>> ( quint8& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }
    QQtLongDataSerialization& operator>> ( quint16& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }
    QQtLongDataSerialization& operator>> ( quint32& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }
    QQtLongDataSerialization& operator>> ( quint64& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }

    QQtLongDataSerialization& operator>> ( QByteArray& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }
    QQtLongDataSerialization& operator>> ( QString& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }
    QQtLongDataSerialization& operator>> ( QImage& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }

    template <typename T>
    QQtLongDataSerialization& operator>> ( T& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }
    QQtLongDataSerialization& operator>> ( QVariant& i ) {
        QQtDataSerialization& ref = *this;
        ref >> i;
        return *this;
    }

    int length() const;
    void dump() const;

protected:

private:

    // QQtMessage interface
public:
    virtual quint16 minlength() const override {
        return 0x08;
    }
    virtual quint16 maxlength() const override {
        return 0xFFFF;
    }
    virtual void packer ( QByteArray& ) const override;
    virtual void parser ( const QByteArray& ) override;
};

#endif // QQTLONGDATASERIALIZATION_H

